/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jard.webshop.management;

import jard.webshop.nbp.Address;
import jard.webshop.nbp.User;
import jard.webshop.util.Constants;
import jard.webshop.util.UserException;
import jard.webshop.util.Utils;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;

/**
 *
 * @author cjp
 */
public class UserManagement {

    private static EntityManagerFactory emf = null;
    
    public static void setEntityManagerFactory(EntityManagerFactory givenEmf) {
        emf = givenEmf;
    }
    
    private static UserManagement um = null;

    public static UserManagement getInstance() {
        if(um == null) {
            um = new UserManagement();
        }
        return um;
    }

    private UserManagement() {
    }
    
    public Boolean isPersisted(User user) {
        if(user == null) {
            return false;
        }
        EntityManager em = emf.createEntityManager();
        User candidate = null;
        try {
            candidate = em.find(User.class, user.getEmailAddress());
        } catch (NoResultException e) {
            return false;
        }

        return candidate != null;
    }

    
    public User makeUser(String email, String password) throws UserException {
        User existing = null;
        try {
            existing = getUser(email);
        } catch(NoResultException e) {
            // Excellent
        }
        if(existing == null) {
            String passwordHash = Utils.hash(password);
            User newUser = new User(email, passwordHash);
            return newUser;
        } else {
            throw new UserException("Email address already in use!");
        }
    }

    public void addUser(User user) {
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();
        em.persist(user);
        tx.commit();
    }
    
    public void saveUser(User user, String oldPassword){
        //TODO Replace old user data with new
        /*EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();
        em.persist(user);
        tx.commit();*/
    }

    public void removeUser(User sub) {
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();
        if (isPersisted(sub)) {
            em.remove(em.merge(sub));
        }
        tx.commit();
    }

    public void invalidateUser(User user) {
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();
        user = em.find(User.class, user.getEmailAddress());
        user.setValid(Boolean.FALSE);
        em.merge(user);
        tx.commit();
    }
    
    public void revalidateUser(User user) {
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();
        user = em.find(User.class, user.getEmailAddress());
        user.setValid(Boolean.TRUE);
        em.merge(user);
        tx.commit();
    }
    
    public void clearPassword(User user) {
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();
        user = em.find(User.class, user.getEmailAddress());
        user.setPassword(Utils.hash(""));
        em.merge(user);
        tx.commit();
    }
    
    public void setEmployee(User user) {
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();
        user = em.find(User.class, user.getEmailAddress());
        user.setAuthLevel(Constants.getEmployeeLevel());
        em.merge(user);
        tx.commit();
    }
    
    public void setAdmin(User user) {
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();
        user = em.find(User.class, user.getEmailAddress());
        user.setAuthLevel(Constants.getAdminLevel());
        em.merge(user);
        tx.commit();
    }

    public User getUser(String email) {
        EntityManager em = emf.createEntityManager();
        
        return em.find(User.class, email);
    }
    
    public User getUser(String email, String password) {
        User candidate = getUser(email);
        String hashword = Utils.hash(password);
        if(candidate != null && candidate.getPassword().equals(hashword)) {
            return candidate;
        } else {
            return null;
        }
    }

    public List<User> getAllUsers() {
        EntityManager em = emf.createEntityManager();
        TypedQuery<User> query = em.createNamedQuery(Constants.GET_ALL_USERS, User.class);
        try {
            List<User> retVal = query.getResultList();
            for (User u : retVal) {
                System.out.println("Returning user " + u);
            }
            return retVal;
        } catch (NoResultException e) {
            return new ArrayList<User>();
        }
    }
}
